﻿using HelperFromTheSkeleton.Common;
using HelperFromTheSkeleton.Convert;
using HelperFromTheSkeleton.Model.WebSocketModels;
using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using System.Reflection;

namespace HelperFromTheSkeleton.WebSocketCore
{
    public class WebSocketEventBus
    {
        private readonly BlockingCollection<EventHandleBandInfo> _eventHandleDataInfo;
        private readonly ILoggerFactory _loggerFactory;

        public WebSocketEventBus(ILoggerFactory loggerFactory)
        {
            _eventHandleDataInfo = new BlockingCollection<EventHandleBandInfo>();
            _loggerFactory = loggerFactory;
        }

        public void Band<eventT, handleT>() where eventT : BaseEventModel, new() where handleT : IBaseHandle<eventT>
        {
            _eventHandleDataInfo.Add(new EventHandleBandInfo { EventName = typeof(eventT).Name, EventType = typeof(eventT), HandleType = typeof(handleT), BaseHandleType = typeof(IBaseHandle<eventT>) });
        }

        public void Band(Type eventType,Type handleType,Type baseHandleType)
        {
            _eventHandleDataInfo.Add(new EventHandleBandInfo { EventName = eventType.Name, EventType = eventType, HandleType = handleType, BaseHandleType = baseHandleType });
        }

        public Task Trigger(string data, WebSocketChannelModel socketChannel)
        {

            return Task.Run(() =>
            {
                try
                {
                    var baseEvent = data.ToObject<BaseEventModel>() ?? throw new InvalidOperationException("无效的事件");
                    var eventHandleData = _eventHandleDataInfo.FirstOrDefault(m => m.EventName == baseEvent.EventName) ?? throw new InvalidOperationException($"找不到事件{baseEvent.EventName}的处理");
                    var handle = Config.GetServer(eventHandleData.BaseHandleType??throw new InvalidOperationException("基础处理类型为空"), 
                                                  eventHandleData.HandleType?? throw new InvalidOperationException("目标处理类型为空")) ?? throw new InvalidOperationException($"找不到事件{baseEvent.EventName}的处理");
                    var @event = data.ToObject(eventHandleData.EventType??throw new InvalidOperationException("事件类型为空"));
                    MethodInfo method = eventHandleData?.HandleType.GetMethod("HandleAsync")??throw new InvalidOperationException("找不到处理方法");
                    method.Invoke(handle, new object?[] { @event, socketChannel});
                    var _logger = _loggerFactory?.CreateLogger("WebSocketAccess"); //WebSocketError
                    _logger?.LogInformation(data);
                }
                catch (Exception ex)
                {
                    var _logger = _loggerFactory.CreateLogger("WebSocketError"); //WebSocketError
                    var errorMessage = "Socket  Event处理错误";
                    _logger?.LogError(ex, errorMessage, new [] { data });
                    if (ex == null) return;
                }
            });
        }
    }

    public class EventHandleBandInfo
    {
        /// <summary>
        /// 事件名称
        /// </summary>
        public string? EventName { get; set; }
        /// <summary>
        /// 事件类型
        /// </summary>
        public Type? EventType { get; set; }

        /// <summary>
        /// 处理类型
        /// </summary>
        public Type? HandleType { get; set; }


        public Type? BaseHandleType { get; set; }
    }
}
